﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Principal;
using System.ServiceModel;
using System.ServiceModel.Activation;
using System.ServiceModel.Channels;
using Framework;
using ISSMoviePlex.BLL;

namespace ISSMoviePlex.Service
{
    //*************************************CONCURRENCY************************************/
    //K: ConcurrencyMode.Single because we need to let client authenticate & authorize before using this service
    //*************************************INSTANCE**************************************/
    //K: In our case, we should use Single because all clients can access the service via ONE instance without any issue
    [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single,
        ConcurrencyMode = ConcurrencyMode.Single)]
    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]
    //IIS(8.0) URL: http://localhost/CineService/MovieService.svc
    public class MovieService : IMovieService
    {
        private readonly MovieBLL _movieLogic = new MovieBLL();

        public MovieCollection GetAllMovies()
        {

            var messageProperty = (HttpRequestMessageProperty)
                OperationContext.Current.IncomingMessageProperties[HttpRequestMessageProperty.Name];
            var cookie = messageProperty.Headers.Get("Set-Cookie");
            var nameValue = cookie.Split('=', ',');
            var userName = string.Empty;

            // Set User Name from cookie
            if (nameValue.Length >= 2)
                userName = nameValue[1];

            if (!Is.NotEmptyString(userName))
            {
                throw new FaultException<AuthorizationFault>(new AuthorizationFault()
                {
                    Operation = "Get Movies",
                    ProblemType = "Login Required!"
                }, "Not Logged In");
            }
            var collection = new MovieCollection();
            collection.AddRange(_movieLogic.GetAllMovies().Select(movie => new Movie()
            {
                MovieId = movie.MovieId,
                MovieName = movie.MovieName,
                MovieCast = movie.Cast,
                MoviePlot = movie.Plot,
                MovieLanguage = movie.Language
            }));

            return collection;
        }

        public MovieCollection GetMovieByGenre(string genre)
        {
            var messageProperty = (HttpRequestMessageProperty)
                OperationContext.Current.IncomingMessageProperties[HttpRequestMessageProperty.Name];
            var cookie = messageProperty.Headers.Get("Set-Cookie");
            var nameValue = cookie.Split('=', ',');
            var userName = string.Empty;

            // Set User Name from cookie
            if (nameValue.Length >= 2)
                userName = nameValue[1];

            if (!Is.NotEmptyString(userName))
            {
                throw new FaultException<AuthorizationFault>(new AuthorizationFault()
                {
                    Operation = "Get Movies",
                    ProblemType = "Login Required!"
                }, "Not Logged In");
            }
            var collection = new MovieCollection();
            collection.AddRange(_movieLogic.GetMovieByGenre(genre).Select(movie => new Movie()
            {
                MovieId = movie.MovieId,
                MovieName = movie.MovieName,
                MovieCast = movie.Cast,
                MoviePlot = movie.Plot,
                MovieLanguage = movie.Language
            }));

            return collection;
        }

        public MovieCollection SearchMovieByTitle(string title)
        {
            var messageProperty = (HttpRequestMessageProperty)
                OperationContext.Current.IncomingMessageProperties[HttpRequestMessageProperty.Name];
            var cookie = messageProperty.Headers.Get("Set-Cookie");
            var nameValue = cookie.Split('=', ',');
            var userName = string.Empty;

            // Set User Name from cookie
            if (nameValue.Length >= 2)
                userName = nameValue[1];

            if (!Is.NotEmptyString(userName))
            {
                throw new FaultException<AuthorizationFault>(new AuthorizationFault()
                {
                    Operation = "Get Movies",
                    ProblemType = "Login Required!"
                }, "Not Logged In");
            }
            var collection = new MovieCollection();
            collection.AddRange(_movieLogic.SearchMovieByTitle(title).Select(movie => new Movie()
            {
                MovieId = movie.MovieId,
                MovieName = movie.MovieName,
                MovieCast = movie.Cast,
                MoviePlot = movie.Plot,
                MovieLanguage = movie.Language
            }));

            return collection;
        }

        //        [PrincipalPermission(SecurityAction.Demand, Role = "Admin")]
        //        [PrincipalPermission(SecurityAction.Demand, Role = "Member")]
        public MovieInSoap GetAllMovieInSoap()
        {
            var messageProperty = (HttpRequestMessageProperty)
                OperationContext.Current.IncomingMessageProperties[HttpRequestMessageProperty.Name];
            var cookie = messageProperty.Headers.Get("Set-Cookie");
            var nameValue = cookie.Split('=', ',');
            var userName = string.Empty;

            // Set User Name from cookie
            if (nameValue.Length >= 2)
                userName = nameValue[1];

            if (!Is.NotEmptyString(userName))
            {
                throw new FaultException<AuthorizationFault>(new AuthorizationFault()
                {
                    Operation = "Get Movies",
                    ProblemType = "Login Required!"
                }, "Not Logged In");
            }
            var movie = new MovieInSoap { MsgTime = DateTime.Now, Movies = new List<Movie>() };
            movie.Movies.AddRange(_movieLogic.GetAllMovies().Select(m => new Movie()
            {
                MovieId = m.MovieId,
                MovieName = m.MovieName,
                MovieCast = m.Cast,
                MoviePlot = m.Plot,
                MovieLanguage = m.Language
            }));
            return movie;
        }
    }

    public class CustomIdentity : IIdentity
    {
        public string AuthenticationType
        {
            get;
            set;
        }

        public bool IsAuthenticated
        {
            get;
            set;
        }

        public string Name
        {
            get;
            set;
        }
    }
}

//            _.P(Thread.CurrentPrincipal.Identity.Name);
//            // Extract Cookie (name=value) from messageproperty
//            var messageProperty = (HttpRequestMessageProperty)
//                OperationContext.Current.IncomingMessageProperties[HttpRequestMessageProperty.Name];
//            var cookie = messageProperty.Headers.Get("Set-Cookie");
//            var nameValue = cookie.Split('=', ',');
//            var userName = string.Empty;
//
//            // Set User Name from cookie
//            if (nameValue.Length >= 2)
//                userName = nameValue[1];
//
//            var customIdentity = new CustomIdentity();
//            var threadCurrentPrincipal = new GenericPrincipal(customIdentity, new[] { "Admin", "Member" });
//            customIdentity.IsAuthenticated = true;
//            customIdentity.Name = userName;
//            HttpContext.Current.User = threadCurrentPrincipal;
//            Thread.CurrentPrincipal = HttpContext.Current.User;
//            _.P(Thread.CurrentPrincipal.Identity.Name);